package com.seek.core;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.springframework.transaction.annotation.Transactional;

import com.seek.model.dto.PageBean;
import com.seek.util.CommonUtil;

/**
 * 
 * @author tuxl
 *
 * @param <T>
 */

public class BaseReadServiceImpl<T extends Serializable> implements BaseReadService<T> {
	
	protected Logger log = Logger.getLogger(BaseReadServiceImpl.class);
	private BaseReadDao<T> dao;

	public void setDao(BaseReadDao<T> dao) {
		this.dao = dao;
	}
	
	protected BaseReadDao<T> getDao() {
		return this.dao;
	}

	/**
	 * 根据ID得到某个实体
	 */
	@Transactional(readOnly = true)
	public T findById(Serializable id) {
		return dao.get(id);
	}

	/**
	 * 根据ID得到某个实体
	 */
	@Transactional(readOnly = true)
	public T load(Serializable id) {
		return dao.load(id);
	}

	/**
	 * 返回某种实体的集合
	 */
	@Transactional(readOnly = true)
	public List<T> findAll() {
		return dao.findAll();
	}

	/**
	 * 根据某个某个属性值得到相应实体个数
	 */
	public int countByProperty(String property, Object value) {
		return dao.countByProperty(property, value);
	}
	
	/**
	 * 根据hql得到相应实体个数
	 */
	public int countByHql(String hql) {
		return dao.getAllRowCount(hql);
	}
	
	/**
	 * 根据某个某个属性值的到实体List
	 */
	public List<T> findByProperty(String property, Object value) {
		return dao.findByProperty(property, value);
	}

	/**
	 * 根据某个某个属性值的到某个实体
	 */
	public T findUniqueByProperty(String property, Object value) {
		return dao.findUniqueByProperty(property, value);
	}

	
	
	/**
	 * 根据Class、ID得到某个实体
	 */
	@Transactional(readOnly = true)
	public T findById(Class<Object> c, Serializable id) {
		return dao.get(c, id);
	}
	
	/**
	 * 根据hql查对象的集合
	 * @param hql
	 * @param offset
	 * @param length
	 * @param values
	 * @return
	 */
	public List<T> findByHql(String hql,int offset,int length,Object...values) {
		return getDao().findByHql(hql, offset, length, values);
	}
	
	public Session getSession(){
		return getDao().getSession();
	}
	
	
	/**
	 * 
	 * queryForPage:分页查询
	 * 
	 * @param hql
	 *            查询语句
	 * @param pageSize
	 *            每页大小
	 * @param page
	 *            当前第几页
	 * @return PageBean 封闭了分页信息(包括记录集list)的Bean
	 */
	public PageBean pageQuery(String listHql,String rowsHql, int pageSize, int page) {

		int allRow = this.dao.getAllRowCount(rowsHql);// 总记录数
		int totalPage = PageBean.countTotalPage(pageSize, allRow);// 总页数
		final int offset = PageBean.countOffset(pageSize, page);// 当前页开始记录
		final int length = pageSize;// 每页记录数
		final int currentPage = PageBean.countCurrentPage(page);
		List<T> list = this.dao.getListForPage(listHql, offset, length);// "一页"的记录

		// 把分页信息保存到Bean中
		PageBean pageBean = new PageBean();
		pageBean.setPageSize(pageSize);
		pageBean.setCurrentPage(currentPage);
		pageBean.setAllRow(allRow);
		pageBean.setTotalPage(totalPage);
		pageBean.setList(list);
		pageBean.init();
		return pageBean;
	}
	
	/**
	 * 
	 * pageQueryBySql:(用SQL语句查询分页)
	 *
	 * @param  @param listSql
	 * @param  @param rowsSql
	 * @param  @param pageSize
	 * @param  @param page
	 * @param  @return 
	 * @return PageBean
	 */
	@SuppressWarnings("unchecked")
	public PageBean pageQueryBySql(String listSql,String rowsSql, int pageSize, int page,Class c) {

		int allRow = this.dao.getAllRowCountBySql(rowsSql);// 总记录数
		int totalPage = PageBean.countTotalPage(pageSize, allRow);// 总页数
		final int offset = PageBean.countOffset(pageSize, page);// 当前页开始记录
		final int length = pageSize;// 每页记录数
		final int currentPage = PageBean.countCurrentPage(page);
		List<T> list = this.dao.getListForPageBySql(listSql, offset, length,c);// "一页"的记录

		// 把分页信息保存到Bean中
		PageBean pageBean = new PageBean();
		pageBean.setPageSize(pageSize);
		pageBean.setCurrentPage(currentPage);
		pageBean.setAllRow(allRow);
		pageBean.setTotalPage(totalPage);
		pageBean.setList(list);
		pageBean.init();
		return pageBean;
	}
	
	/**
	 * 分页查询，返回pagebean（map）
	 */
	public PageBean pageQueryMapBySql(String listSql,String rowsSql, int pageSize, int page) {
		
		int allRow = this.dao.getAllRowCountBySql(rowsSql);// 总记录数
		int totalPage = PageBean.countTotalPage(pageSize, allRow);// 总页数
		final int offset = PageBean.countOffset(pageSize, page);// 当前页开始记录
		final int length = pageSize;// 每页记录数
		final int currentPage = PageBean.countCurrentPage(page);
		List list = this.dao.getListMapForPageBySql(listSql, offset, length);// "一页"的记录
		
		// 把分页信息保存到Bean中
		PageBean pageBean = new PageBean();
		pageBean.setPageSize(pageSize);
		pageBean.setCurrentPage(currentPage);
		pageBean.setAllRow(allRow);
		pageBean.setTotalPage(totalPage);
		pageBean.setList(list);
		pageBean.init();
		return pageBean;
	}

	public List<T> findBySql(String sql, Object... values){
	    return dao.findBySql(sql, values);
	}
	
	public int executeUpdate(String sql, Object... values) throws Exception{
		return dao.executeUpdateSqlWithRetun(sql, values);
	}
	
	@SuppressWarnings("rawtypes")
	public List findMapBySql(String sql, Object... values){
    	return this.getDao().findMapBySql(sql, values);
    }
    
    @SuppressWarnings("unchecked")
	public Map<String,Object> findOneMapBySql(String sql, Object... values){
    	List<Map<String,Object>> ds = this.findMapBySql(sql, values);
    	if (ds == null || ds.size() < 1)
    		return null;
    	return ds.get(0);
    }
    
    @SuppressWarnings("unchecked")
    public Map<String,Object> pageQueryBySql(String listSql,String rowsSql, int pageSize, int page, Object[] params) {
		// 取得总记录数
    	Map<String,Object> ret = new HashMap<String,Object>();
    	List<Map<String,Object>> ds = this.dao.findMapBySql(rowsSql, params);
    	int rowCount = 0;
		if (ds == null || ds.size()<1)
			ret.put("rowCount", 0);
		else{
			rowCount = CommonUtil.getIntValue(ds.get(0).get("cnt"));
			ret.put("rowCount", rowCount);
		}
		if (rowCount > 0){
			if (page<1)
				page = 1;
			if (pageSize < 1)
				pageSize = 25; 

			int startRow = (page - 1) * (pageSize);
			int endRow = pageSize;
			listSql += " limit " + startRow + "," + endRow;
			ret.put("datas", this.dao.findMapBySql(listSql, params));
		}else{
			ret.put("datas", new ArrayList<Map<String,Object>>());
		}
		
    	return ret;
	}
}
